package es.mfp.practicos.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

import es.mfp.practicos.util.DNI;

@Entity
@Table(name = "EMPLEADO", uniqueConstraints = @UniqueConstraint(columnNames = { "nif" }))
public class Empleado extends Registro implements Serializable {

	private static final long serialVersionUID = 1L;

	@NotEmpty(message = "El primer apellido es obligatorio")
	@Size(max = 50)
	private String apellido1;

	@NotEmpty(message = "El segundo apellido es obligatorio")
	@Size(max = 50)
	private String apellido2;

	@NotEmpty(message = "El nombre es obligatorio")
	@Size(max = 50)
	private String nombre;

	@DNI
	@NotEmpty(message = "El NIF/CIF es obligatorio")
	@Size(max = 9, message = "El NIF/CIF no puede exceder 9 caracteres.")
	@Column(name = "nif")
	private String nif;

	@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
	private Set<LineaTelefonica> lineas = null;

	@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
	private Set<ConsumoPuntos> consumos = null;

	public String getApellido1() {
		return apellido1;
	}

	public void setApellido1(String apellido1) {
		this.apellido1 = apellido1;
	}

	public String getApellido2() {
		return apellido2;
	}

	public void setApellido2(String apellido2) {
		this.apellido2 = apellido2;
	}

	public String getNombre() {
		return nombre;
	}

	public void setNombre(String nombre) {
		this.nombre = nombre;
	}

	public String getNif() {
		return nif;
	}

	public void setNif(String nif) {
		if (nif != null) {
			nif = nif.toUpperCase();
		}
		this.nif = nif;
	}

	public Integer getPuntos() {
		if (consumos == null || consumos.isEmpty()) {
			return 0;
		}

		Integer res = 0;
		for (ConsumoPuntos c : consumos) {
			// tan solo ignoramos el caso de estar asociado a una linea de
			// factura o a una factura dada
			// de baja
			if (c.getLineaFactura() != null
					&& (c.getLineaFactura().getEstado() == Estado.INACTIVO || c
							.getLineaFactura().getFactura().getEstado() == Estado.INACTIVO)) {
				continue;
			}
			res += c.getPuntosConsumidos();
		}

		return res;
	}

	public Set<LineaTelefonica> getLineas() {
		return lineas;
	}

	public void setLineas(Set<LineaTelefonica> lineas) {
		this.lineas = lineas;
	}

	public Set<ConsumoPuntos> getConsumos() {
		return consumos;
	}

	public List<ConsumoPuntos> getConsumosList() {
		if (consumos == null) {
			return null;
		}
		List<ConsumoPuntos> res = new ArrayList<ConsumoPuntos>(consumos.size());

		for (ConsumoPuntos c : consumos) {
			res.add(c);
		}

		Collections.sort(res);

		return res;
	}

	public List<LineaTelefonica> getLineasList() {
		if (lineas == null) {
			return null;
		}
		List<LineaTelefonica> res = new ArrayList<LineaTelefonica>(
				lineas.size());

		for (LineaTelefonica c : lineas) {
			res.add(c);
		}

		Collections.sort(res);

		return res;
	}

	public void setConsumos(Set<ConsumoPuntos> consumos) {
		this.consumos = consumos;
	}

	public void addConsumo(ConsumoPuntos consumo) {
		if (consumos == null) {
			consumos = new HashSet<ConsumoPuntos>();
		}

		consumos.add(consumo);

	}

	public void addLinea(LineaTelefonica linea) {
		if (lineas == null) {
			lineas = new HashSet<LineaTelefonica>();
		}

		linea.setTitular(this);
		lineas.add(linea);

	}

	public String getPresentacion() {
		return nombre + " " + apellido1 + " " + apellido2;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Empleado)) {
			return false;
		}
		Empleado o = (Empleado) obj;

		if (this.getId() == null || o.getId() == null) {
			return false;
		}
		return (this.getId().equals(o.getId()));

	}

	@Override
	public String toString() {
		return "[empleado:" + getId() + " --- " + apellido1 + ", " + apellido2
				+ ", " + nombre + "]";
	}

}
